<?php

/**
 * SolicitationsApi
 * PHP version 8.3.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */

/**
 * Selling Partner API for Solicitations.
 *
 * With the Solicitations API you can build applications that send non-critical solicitations to buyers. You can get a list of solicitation types that are available for an order that you specify, then call an operation that sends a solicitation to the buyer for that order. Buyers cannot respond to solicitations sent by this API, and these solicitations do not appear in the Messaging section of Seller Central or in the recipient's Message Center. The Solicitations API returns responses that are formed according to the <a href=https://tools.ietf.org/html/draft-kelly-json-hal-08>JSON Hypertext Application Language</a> (HAL) standard.
 *
 * The version of the OpenAPI document: v1
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.9.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace SpApi\Api\solicitations\v1;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use SpApi\ApiException;
use SpApi\AuthAndAuth\RestrictedDataTokenSigner;
use SpApi\Configuration;
use SpApi\HeaderSelector;
use SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse;
use SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse;
use SpApi\ObjectSerializer;
use Symfony\Component\RateLimiter\LimiterInterface;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;

/**
 * SolicitationsApi Class Doc Comment.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */
class SolicitationsApi
{
    public ?LimiterInterface $createProductReviewAndSellerFeedbackSolicitationRateLimiter;
    public ?LimiterInterface $getSolicitationActionsForOrderRateLimiter;
    protected ClientInterface $client;

    protected Configuration $config;

    protected HeaderSelector $headerSelector;

    /**
     * @var int Host index
     */
    protected int $hostIndex;

    private bool $rateLimiterEnabled;
    private InMemoryStorage $rateLimitStorage;

    /**
     * @param int $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        Configuration $config,
        ?ClientInterface $client = null,
        ?bool $rateLimiterEnabled = true,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->config = $config;
        $this->rateLimiterEnabled = $rateLimiterEnabled;

        if ($rateLimiterEnabled) {
            $this->rateLimitStorage = new InMemoryStorage();

            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('SolicitationsApi-createProductReviewAndSellerFeedbackSolicitation'), $this->rateLimitStorage);
            $this->createProductReviewAndSellerFeedbackSolicitationRateLimiter = $factory->create('SolicitationsApi-createProductReviewAndSellerFeedbackSolicitation');
            $factory = new RateLimiterFactory(Configuration::getRateLimitOptions('SolicitationsApi-getSolicitationActionsForOrder'), $this->rateLimitStorage);
            $this->getSolicitationActionsForOrderRateLimiter = $factory->create('SolicitationsApi-getSolicitationActionsForOrder');
        }

        $this->client = $client ?: new Client();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index.
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex(int $hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index.
     *
     * @return int Host index
     */
    public function getHostIndex(): int
    {
        return $this->hostIndex;
    }

    public function getConfig(): Configuration
    {
        return $this->config;
    }

    /**
     * Operation createProductReviewAndSellerFeedbackSolicitation.
     *
     * @param string      $amazon_order_id
     *                                         An Amazon order identifier. This specifies the order for which a solicitation is sent. (required)
     * @param string[]    $marketplace_ids
     *                                         A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     * @param null|string $restrictedDataToken Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function createProductReviewAndSellerFeedbackSolicitation(
        string $amazon_order_id,
        array $marketplace_ids,
        ?string $restrictedDataToken = null
    ): CreateProductReviewAndSellerFeedbackSolicitationResponse {
        list($response) = $this->createProductReviewAndSellerFeedbackSolicitationWithHttpInfo($amazon_order_id, $marketplace_ids, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation createProductReviewAndSellerFeedbackSolicitationWithHttpInfo.
     *
     * @param string      $amazon_order_id
     *                                         An Amazon order identifier. This specifies the order for which a solicitation is sent. (required)
     * @param string[]    $marketplace_ids
     *                                         A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     * @param null|string $restrictedDataToken Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function createProductReviewAndSellerFeedbackSolicitationWithHttpInfo(
        string $amazon_order_id,
        array $marketplace_ids,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->createProductReviewAndSellerFeedbackSolicitationRequest($amazon_order_id, $marketplace_ids);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'SolicitationsApi-createProductReviewAndSellerFeedbackSolicitation');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->createProductReviewAndSellerFeedbackSolicitationRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation createProductReviewAndSellerFeedbackSolicitationAsync.
     *
     * @param string   $amazon_order_id
     *                                  An Amazon order identifier. This specifies the order for which a solicitation is sent. (required)
     * @param string[] $marketplace_ids
     *                                  A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createProductReviewAndSellerFeedbackSolicitationAsync(
        string $amazon_order_id,
        array $marketplace_ids
    ): PromiseInterface {
        return $this->createProductReviewAndSellerFeedbackSolicitationAsyncWithHttpInfo($amazon_order_id, $marketplace_ids)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation createProductReviewAndSellerFeedbackSolicitationAsyncWithHttpInfo.
     *
     * @param string   $amazon_order_id
     *                                  An Amazon order identifier. This specifies the order for which a solicitation is sent. (required)
     * @param string[] $marketplace_ids
     *                                  A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createProductReviewAndSellerFeedbackSolicitationAsyncWithHttpInfo(
        string $amazon_order_id,
        array $marketplace_ids,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\solicitations\v1\CreateProductReviewAndSellerFeedbackSolicitationResponse';
        $request = $this->createProductReviewAndSellerFeedbackSolicitationRequest($amazon_order_id, $marketplace_ids);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'SolicitationsApi-createProductReviewAndSellerFeedbackSolicitation');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->createProductReviewAndSellerFeedbackSolicitationRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'createProductReviewAndSellerFeedbackSolicitation'.
     *
     * @param string   $amazon_order_id
     *                                  An Amazon order identifier. This specifies the order for which a solicitation is sent. (required)
     * @param string[] $marketplace_ids
     *                                  A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function createProductReviewAndSellerFeedbackSolicitationRequest(
        string $amazon_order_id,
        array $marketplace_ids
    ): Request {
        // verify the required parameter 'amazon_order_id' is set
        if (null === $amazon_order_id || (is_array($amazon_order_id) && 0 === count($amazon_order_id))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_order_id when calling createProductReviewAndSellerFeedbackSolicitation'
            );
        }
        // verify the required parameter 'marketplace_ids' is set
        if (null === $marketplace_ids || (is_array($marketplace_ids) && 0 === count($marketplace_ids))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling createProductReviewAndSellerFeedbackSolicitation'
            );
        }
        if (count($marketplace_ids) > 1) {
            throw new \InvalidArgumentException('invalid value for "$marketplace_ids" when calling SolicitationsApi.createProductReviewAndSellerFeedbackSolicitation, number of items must be less than or equal to 1.');
        }

        $resourcePath = '/solicitations/v1/orders/{amazonOrderId}/solicitations/productReviewAndSellerFeedback';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $marketplace_ids,
            'marketplaceIds', // param base name
            'array', // openApiType
            'form', // style
            false, // explode
            true, // required
            $this->config
        ) ?? []);

        // path params
        if (null !== $amazon_order_id) {
            $resourcePath = str_replace(
                '{amazonOrderId}',
                ObjectSerializer::toPathValue($amazon_order_id),
                $resourcePath
            );
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/hal+json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'POST',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getSolicitationActionsForOrder.
     *
     * @param string      $amazon_order_id
     *                                         An Amazon order identifier. This specifies the order for which you want a list of available solicitation types. (required)
     * @param string[]    $marketplace_ids
     *                                         A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     * @param null|string $restrictedDataToken Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function getSolicitationActionsForOrder(
        string $amazon_order_id,
        array $marketplace_ids,
        ?string $restrictedDataToken = null
    ): GetSolicitationActionsForOrderResponse {
        list($response) = $this->getSolicitationActionsForOrderWithHttpInfo($amazon_order_id, $marketplace_ids, $restrictedDataToken);

        return $response;
    }

    /**
     * Operation getSolicitationActionsForOrderWithHttpInfo.
     *
     * @param string      $amazon_order_id
     *                                         An Amazon order identifier. This specifies the order for which you want a list of available solicitation types. (required)
     * @param string[]    $marketplace_ids
     *                                         A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     * @param null|string $restrictedDataToken Restricted Data Token (RDT) for accessing restricted resources (optional, required for operations that return PII)
     *
     * @return array of \SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse, HTTP status code, HTTP response headers (array of strings)
     *
     * @throws ApiException              on non-2xx response
     * @throws \InvalidArgumentException
     */
    public function getSolicitationActionsForOrderWithHttpInfo(
        string $amazon_order_id,
        array $marketplace_ids,
        ?string $restrictedDataToken = null
    ): array {
        $request = $this->getSolicitationActionsForOrderRequest($amazon_order_id, $marketplace_ids);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'SolicitationsApi-getSolicitationActionsForOrder');
        } else {
            $request = $this->config->sign($request);
        }

        try {
            $options = $this->createHttpClientOption();

            try {
                if ($this->rateLimiterEnabled) {
                    $this->getSolicitationActionsForOrderRateLimiter->consume()->ensureAccepted();
                }
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getResponse()->getBody()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }
            if ('\SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse' === '\SplFileObject') {
                $content = $response->getBody(); // stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ('\SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse' !== 'string') {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, '\SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse', []),
                $response->getStatusCode(),
                $response->getHeaders(),
            ];
        } catch (ApiException $e) {
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);

            throw $e;
        }
    }

    /**
     * Operation getSolicitationActionsForOrderAsync.
     *
     * @param string   $amazon_order_id
     *                                  An Amazon order identifier. This specifies the order for which you want a list of available solicitation types. (required)
     * @param string[] $marketplace_ids
     *                                  A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function getSolicitationActionsForOrderAsync(
        string $amazon_order_id,
        array $marketplace_ids
    ): PromiseInterface {
        return $this->getSolicitationActionsForOrderAsyncWithHttpInfo($amazon_order_id, $marketplace_ids)
            ->then(
                function ($response) {
                    return $response[0];
                }
            )
        ;
    }

    /**
     * Operation getSolicitationActionsForOrderAsyncWithHttpInfo.
     *
     * @param string   $amazon_order_id
     *                                  An Amazon order identifier. This specifies the order for which you want a list of available solicitation types. (required)
     * @param string[] $marketplace_ids
     *                                  A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function getSolicitationActionsForOrderAsyncWithHttpInfo(
        string $amazon_order_id,
        array $marketplace_ids,
        ?string $restrictedDataToken = null
    ): PromiseInterface {
        $returnType = '\SpApi\Model\solicitations\v1\GetSolicitationActionsForOrderResponse';
        $request = $this->getSolicitationActionsForOrderRequest($amazon_order_id, $marketplace_ids);
        if (null !== $restrictedDataToken) {
            $request = RestrictedDataTokenSigner::sign($request, $restrictedDataToken, 'SolicitationsApi-getSolicitationActionsForOrder');
        } else {
            $request = $this->config->sign($request);
        }
        if ($this->rateLimiterEnabled) {
            $this->getSolicitationActionsForOrderRateLimiter->consume()->ensureAccepted();
        }

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ('\SplFileObject' === $returnType) {
                        $content = $response->getBody(); // stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('string' !== $returnType) {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();

                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            )
        ;
    }

    /**
     * Create request for operation 'getSolicitationActionsForOrder'.
     *
     * @param string   $amazon_order_id
     *                                  An Amazon order identifier. This specifies the order for which you want a list of available solicitation types. (required)
     * @param string[] $marketplace_ids
     *                                  A marketplace identifier. This specifies the marketplace in which the order was placed. Only one marketplace can be specified. (required)
     *
     * @throws \InvalidArgumentException
     */
    public function getSolicitationActionsForOrderRequest(
        string $amazon_order_id,
        array $marketplace_ids
    ): Request {
        // verify the required parameter 'amazon_order_id' is set
        if (null === $amazon_order_id || (is_array($amazon_order_id) && 0 === count($amazon_order_id))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $amazon_order_id when calling getSolicitationActionsForOrder'
            );
        }
        // verify the required parameter 'marketplace_ids' is set
        if (null === $marketplace_ids || (is_array($marketplace_ids) && 0 === count($marketplace_ids))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling getSolicitationActionsForOrder'
            );
        }
        if (count($marketplace_ids) > 1) {
            throw new \InvalidArgumentException('invalid value for "$marketplace_ids" when calling SolicitationsApi.getSolicitationActionsForOrder, number of items must be less than or equal to 1.');
        }

        $resourcePath = '/solicitations/v1/orders/{amazonOrderId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $marketplace_ids,
            'marketplaceIds', // param base name
            'array', // openApiType
            'form', // style
            false, // explode
            true, // required
            $this->config
        ) ?? []);

        // path params
        if (null !== $amazon_order_id) {
            $resourcePath = str_replace(
                '{amazonOrderId}',
                ObjectSerializer::toPathValue($amazon_order_id),
                $resourcePath
            );
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/hal+json'],
            '',
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif ('application/json' === $headers['Content-Type']) {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams, $this->config);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = ObjectSerializer::buildQuery($queryParams, $this->config);

        return new Request(
            'GET',
            $this->config->getHost().$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option.
     *
     * @return array of http client options
     *
     * @throws \RuntimeException on file opening failure
     */
    protected function createHttpClientOption(): array
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: '.$this->config->getDebugFile());
            }
        }

        return $options;
    }
}
